package com.bsh.serviceImpl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.bsh.api.ApiUtils;
import com.bsh.api.Exception.ApiException;
import com.bsh.mybatis.model.Account;
import com.bsh.mybatis.model.AccountNotice;
import com.bsh.mybatis.model.Payment;
import com.bsh.mybatis.model.User;
import com.bsh.mybatis.model.UserBank;
import com.bsh.repository.DaoAccount;
import com.bsh.repository.DaoAccountLog;
import com.bsh.repository.DaoAccountNotice;
import com.bsh.repository.DaoPayment;
import com.bsh.repository.DaoSysConfig;
import com.bsh.service.AccountNoticeService;
import com.bsh.service.AccountService;
import com.bsh.service.ApiFinanceService;
import com.bsh.service.FinanceService;
import com.bsh.service.SmsService;
import com.bsh.service.UserBankService;
import com.bsh.service.UserService;
import com.bsh.service.UserVerifyService;
import com.bsh.utils.ApiMessage;
import com.bsh.utils.Des3;
import com.bsh.utils.DesUtils;
import com.bsh.utils.Pager;
import com.bsh.utils.PrimaryGenerater;
import com.bsh.utils.system.smsApi.SmsNotice;

@Service
public class ApiFinanceServiceImpl implements ApiFinanceService {
    private static Logger log = LoggerFactory
            .getLogger(ApiFinanceServiceImpl.class);
    @Autowired
    UserService servUser;
    @Autowired
    SmsService servSms;
    @Autowired
    AccountService accountServ;
    @Autowired
    DaoAccountLog daoAccLog;
    @Autowired
    DaoAccount daoAcc;
    @Autowired
    DaoAccountNotice daoNotice;
    @Autowired
    DaoPayment daoPay;
    @Autowired
    FinanceService financeService;
    @Autowired
    AccountNoticeService accountNoticeService;
    @Autowired
    UserBankService userBankService;
    @Autowired
    SmsNotice sms;
    @Autowired
    UserVerifyService userVerifyService;
    @Autowired
    DaoSysConfig  sysDao;

    
    

    @Override
    public ApiMessage transferByBalance(JSONObject dto) throws ApiException {
        ApiMessage msg = null;
        ApiUtils.checkUserNameToken(dto);
        if (dto.getString("paypassword") == null) {
            throw new ApiException("400", "请输入支付密码");
        }
        if (dto.getBigDecimal("money") == null
                || dto.getBigDecimal("money").compareTo(new BigDecimal("0.00")) == 0
                || dto.getBigDecimal("money").compareTo(new BigDecimal("0.00")) == -1) {
            throw new ApiException("400", "请输入正确的转账金额");
        }
        if (dto.getBigDecimal("money").compareTo(new BigDecimal("0.01")) == -1) {
            throw new ApiException("400", "转账金额大于0.01");
        }

        User toUser = servUser.getUserByMobile(dto.getString("toMobile"));
        if (toUser == null) {
            throw new ApiException("400", "手机号:" + dto.getString("toMobile") + " 无此用户");
        }
        if (dto.getString("userName").equals(toUser.getName())) {
            throw new ApiException("400", "不能给自己转帐");
        }
        // 查询自己
        User userInfo = servUser.getUserByName(dto.getString("userName"));
        if (userInfo == null) {
            throw new ApiException("400", dto.getString("userName") + "用户不存在");
        }
        if (userInfo.getIsEffect() != 1) {
            throw new ApiException("400", "用户未检验, 联系客服解冻");
        }
        // 支付密码
        Account accInfo = accountServ.getAccountByUserId(userInfo.getId());
        if (accInfo == null) {
            // 没有账号记录
            throw new ApiException("400", "账号" + dto.getString("userName") + "错误");
        }

        DesUtils des = new DesUtils();
        if (accInfo.getPayPassword() == null) {
            // 如果没有支付密码 ，默认支付密码为登录
            if (userInfo.getPassword().equals(
                    des.encryptPassword(dto.getString("paypassword")))) {
                Account changePwd = new Account();
                changePwd = accInfo;
                changePwd.setPayPassword(userInfo.getPassword());
                // 更新支付密码为登录密码
                accountServ.editAccountPassword(changePwd);
            } else {
                throw new ApiException("400", "支付密码不正确");
            }
        } else {
            if (!accInfo.getPayPassword().equals(
                    des.encryptPassword(dto.getString("paypassword")))) {
                throw new ApiException("400", "支付密码错误");
            }
        }
        // 查询余额
        if (accInfo.getMoney().compareTo(dto.getBigDecimal("money")) == -1) {
            throw new ApiException("400", "转账失败，余额不足");
        }
        // 操作account
        String ip = ApiUtils.objIsNotEmpty(dto.getString("req_ip"))?dto.getString("req_ip"):dto.getString("ip");
        Integer res = accountServ.financeTransferBalance(dto.getString("userName"),toUser.getName(), dto.getBigDecimal("money"), ip, dto.getString("memo"));
        if (res > 0) {
            msg = new ApiMessage("200", "用余额转帐给  " + toUser.getName() + " , "+ dto.getBigDecimal("money") + " 元成功");
        } else {
            throw new ApiException("400", "转账操作失败" + res);
        }
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("token", dto.getString("token"));
        msg.setData(Des3.encResponse(data));
        return msg;
    }

    @Override
    public ApiMessage userRecharge(JSONObject dto) throws ApiException {
        ApiMessage msg = null;
        ApiUtils.checkUserNameToken(dto);
        //Integer limitMoney = sysDao.getDayRechargeLimit();
        Integer limitMoney = sysDao.findSysKey("day_recharge_limit");

        if (ApiUtils.objIsEmpty(dto.getBigDecimal("money")) || dto.getBigDecimal("money").compareTo(new BigDecimal("0.00")) <= 0) {
            throw new ApiException("400", "请输入正确的金额");
        }else if(ApiUtils.objIsNotEmpty(limitMoney)&&dto.getBigDecimal("money").compareTo(new BigDecimal(limitMoney))>0){
            throw new ApiException("400", "大额充值请转账到公司账户");
        }
        if (ApiUtils.objIsEmpty(dto.getString("paymentType"))) {
            throw new ApiException("400", "请选择支付方式 ");
        }
        
        
        Payment payment = daoPay.getPaymentByClassName(dto.getString("paymentType"));
        if (ApiUtils.objIsEmpty(payment)||"Balance".equals(dto.getString("paymentType"))) {
            throw new ApiException("400", "支付方式不正确 ");
        }
        User userInfo = servUser.getUserByName(dto.getString("userName"));
        if (ApiUtils.objIsEmpty(userInfo)) {
            throw new ApiException("400", "用户不存在");
        }
        // 支付密码
        Account accInfo = accountServ.getAccountByUserId(userInfo.getId());
        if (accInfo == null) {
            throw new ApiException("400", "账户不存在");
        }
        //充值限额
        BigDecimal sumDayRecharge=new BigDecimal(daoNotice.getSumDayRecharge(userInfo.getId()));
        if(dto.getBigDecimal("money").add(sumDayRecharge).compareTo(new BigDecimal(limitMoney))>0){
            throw new ApiException("400", "超过当日充值限额，请明天再试");
        }
        // 没有放入 service
        Integer accountId = accInfo.getId();
        Integer userid = userInfo.getId();
        String ip = ApiUtils.objIsNotEmpty(dto.getString("req_ip"))?dto.getString("req_ip"):dto.getString("ip");
        String sn = PrimaryGenerater.getInstance().next();
        // 账户变动前记录日志
        daoAccLog.addLog(accountId, sn, ip);
        // 记录notice 返回sn流水号
        AccountNotice notice = new AccountNotice();
        notice.setAccountId(accountId);
        notice.setUserid(userid);
        notice.setMoney(dto.getBigDecimal("money"));// 现金
        notice.setTradeType(1); // 充值
        notice.setSn(sn);// 唯一流水号
        // desc 32字节，一个汉字2个字节
        String desc = String.format(userInfo.getName() + "充值+%s元 ",
                dto.getBigDecimal("money"));
        notice.setTitle(desc);
        notice.setPaymentId(payment.getId());
        notice.setBankCard(dto.getString("bankCard"));
        notice.setBankName(dto.getString("bandName"));
        notice.setIp(ip);
        notice.setIsPaid((byte) 0);// 初始为0
        notice.setMoneyType((short) 1);// 现金类型
        notice.setCreateTime(new Date());
        // 在查
        Account downAccInfo = daoAcc.selectByPrimaryKey(accountId);
        notice.setMoneyDown(downAccInfo.getMoney()); // 结存现金余额
        notice.setCloudMoneyDown(downAccInfo.getCloudMoney()); // 结存商币余额
        Integer res = daoNotice.insert(notice);

        if (res > 0) {
            msg = new ApiMessage("200", "提交成功等待支付");
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("token", dto.getString("token"));
            data.put("sn", sn);
            data.put("money", dto.getBigDecimal("money"));
            data.put("desc", desc);
            msg.setData(Des3.encResponse(data));
        } else {
            throw new ApiException("400", "提交失败");
        }
        return msg;
    }

    @Override
    public ApiMessage transferByOnline(JSONObject dto) throws ApiException {
        ApiMessage msg = null;
//        ApiUtils.checkUserNameToken(dto);
//        User user = servUser.getUserByName(dto.getString("userName"));
//        if (ApiUtils.objIsEmpty(user)) {
//            throw new ApiException("102", "用户不存在");
//        }
//        if (user.getIsEffect() != 1) {
//            throw new ApiException("400", "用户未检验, 联系客服解冻");
//        }
//        Account accInfo = accountServ.getAccountByUserId(user.getId());
//        if (ApiUtils.objIsEmpty(accInfo)) {
//            throw new ApiException("102", "账户不存在");
//        }
//        User toUser = servUser.getUserByMobile(dto.getString("toMobile"));
//        if (toUser == null) {
//            throw new ApiException("400", "手机号:" + dto.getString("toMobile") + " 无此用户");
//        }
//        if (dto.getString("userName").equals(toUser.getName())) {
//            throw new ApiException("400", "不能给自己转帐");
//        }
//        Account toAccInfo = accountServ.getAccountByUserId(toUser.getId());
//        if (ApiUtils.objIsEmpty(toAccInfo)) {
//            throw new ApiException("102", "收款账户不存在");
//        }
//        if (dto.getString("paypassword") == null) {
//            throw new ApiException("400", "请输入支付密码");
//        }
//        if (dto.getBigDecimal("money") == null
//                || dto.getBigDecimal("money").compareTo(new BigDecimal("0.00")) == 0
//                || dto.getBigDecimal("money").compareTo(new BigDecimal("0.00")) == -1) {
//            throw new ApiException("400", "请输入正确的转账金额");
//        }
//        if (dto.getBigDecimal("money").compareTo(new BigDecimal("0.01")) == -1) {
//            throw new ApiException("400", "转账金额大于0.01");
//        }
//        DesUtils des = new DesUtils();
//        if (accInfo.getPayPassword() == null) {
//            // 如果没有支付密码 ，默认支付密码为登录
//            if (user.getPassword().equals(
//                    des.encryptPassword(dto.getString("paypassword")))) {
//                Account changePwd = new Account();
//                changePwd = accInfo;
//                changePwd.setPayPassword(user.getPassword());
//                // 更新支付密码为登录密码
//                accountServ.editAccountPassword(changePwd);
//            } else {
//                throw new ApiException("400", "支付密码不正确");
//            }
//        } else {
//            if (!accInfo.getPayPassword().equals(
//                    des.encryptPassword(dto.getString("paypassword")))) {
//                throw new ApiException("400", "支付密码错误");
//            }
//
//        }
//        Payment payment = daoPay.getPaymentByClassName(dto.getString("paymentType"));
//        if (payment == null) {
//            throw new ApiException("400", "支付方式不正确 ");
//        }
//        // 操作account
//        String ip = ApiUtils.objIsNotEmpty(dto.getString("req_ip"))?dto.getString("req_ip"):dto.getString("ip");
//        DtoTransferBalance result = accountServ.financeTransferOnline(
//                dto.getString("userName"), toUser.getName(), dto.getBigDecimal("money"), ip,
//                dto.getString("memo"), dto.getString("paymentType"));
//        if (result.getRes() > 0) {
//            msg = new ApiMessage("200", "提交成功,等待付款");
//        } else {
//            String message = "转账操作失败";
//            if (result.getMessage() != null) {
//                message = result.getMessage();
//            }
//            throw new ApiException("400", message);
//        }
//
//        Map<String, Object> data = new HashMap<String, Object>();
//        data.put("token", dto.getString("token"));
//        data.put("sn", result.getSn());
//        data.put("money", result.getMoney());
//        data.put("desc", result.getDesc());
//        data.put("paymentType", result.getPaymentType());
//        msg.setData(Des3.encResponse(data));
        msg = new ApiMessage("400", "会员升级请使用【余额支付】");
        return msg;
    }

    @Override
    public ApiMessage withdrawl(JSONObject dto) throws ApiException {
        ApiMessage msg = null;
	    ApiUtils.checkUserNameToken(dto);
        if (ApiUtils.objIsEmpty(dto
                .getInteger("withdrawalMoney"))) {
            throw new ApiException("105", "缺少提款金额");
        }

        if (ApiUtils.objIsEmpty(dto.getString("payPassword"))) {
            throw new ApiException("105", "缺少提现密码");
        }
        if (ApiUtils.objIsEmpty(dto.getInteger("userBankId"))) {
            throw new ApiException("105", "缺少银行卡号");
        }
        User user = servUser.getUserByName(dto.getString("userName"));
        if (ApiUtils.objIsEmpty(user)) {
            throw new ApiException("102", "用户不存在");
        }
        Account accInfo = accountServ.getAccountByUserId(user.getId());
        if (ApiUtils.objIsEmpty(accInfo)) {
            throw new ApiException("102", "账户不存在");
        }
        if (accInfo.getMoney().compareTo(
                new BigDecimal(dto.getInteger("withdrawalMoney"))) == -1) {
            throw new ApiException("102", "提款余额不足");
        }
        if(dto.getInteger("withdrawalMoney")<=0||dto.getInteger("withdrawalMoney")%100!=0){
            throw new ApiException("102", "提款金额必须为100的正整数倍");
        }
        UserBank userBank = userBankService.selectUserOneBankCard(
                dto.getInteger("userBankId"), user.getId());
        if (ApiUtils.objIsEmpty(userBank)) {
            throw new ApiException("102", "用户银行卡不存在");
        }
        // 支付密码校验
        DesUtils des = new DesUtils();
        if (accInfo.getPayPassword() == null) {
            // 如果没有支付密码 ，默认支付密码为登录
            if (user.getPassword().equals(
                    des.encryptPassword(dto.getString("payPassword")))) {
                Account changePwd = new Account();
                changePwd = accInfo;
                changePwd.setPayPassword(user.getPassword());
                // 更新支付密码为登录密码
                accountServ.editAccountPassword(changePwd);
            } else {
                throw new ApiException("400", "支付密码错误");
            }
        }

        if (!accInfo.getPayPassword().equals(
                des.encryptPassword(dto.getString("payPassword")))) {
            throw new ApiException("400", "支付密码错误");
        }


        //查询是否实名认证
        boolean isVerify = userVerifyService.checkUserVerify(user.getId());
        if (!isVerify){
            throw new ApiException("400", "请先实名认证!");
        }


        // 先添加提款记录
        int res = financeService.saveAccRef(accInfo.getId(),
                accInfo.getUserid(), dto.getInteger("userBankId"),
                dto.getInteger("withdrawalMoney"), dto.getString("memo"));
        if (!(res > 0)) {
            throw new ApiException("400", "提款记录保存失败");
        }
        String sn = PrimaryGenerater.getInstance().next();
        String ip = ApiUtils.objIsNotEmpty(dto.getString("req_ip"))?dto.getString("req_ip"):dto.getString("ip");
        String bankName = userBank.getBankName();
        if (ApiUtils.objIsNotEmpty(userBank.getBankZone())) {
            bankName = bankName + userBank.getBankZone();
        }

        res = financeService.withdrawalMoney(accInfo.getId(),
                accInfo.getUserid(), sn, ip, dto.getInteger("withdrawalMoney"),
                userBank.getBankCard(), bankName, dto.getString("memo"));
        if (res > 0) {
            msg = new ApiMessage("200", "提款请求成功");
            try {
                if (dto.getInteger("withdrawalMoney") > 100000) {
                    sms.sendCashNotice(user.getMobile(),
                            String.valueOf(dto.getInteger("withdrawalMoney")));
                }
            } catch (Exception e) {
                log.error("发送大额提款请求短信失败");
                e.printStackTrace();
            }
        } else {
            throw new ApiException("400", "提款请求失败");
        }
        return msg;
    }

    @Override
    public ApiMessage withdrawlList(JSONObject dto) throws ApiException {
        ApiMessage msg = null;
        if (ApiUtils.objIsEmpty(dto.getString("userName"))) {
            throw new ApiException("105", "缺少用户名");
        }
        if (ApiUtils.objIsEmpty(dto.getString("token"))) {
            throw new ApiException("103", "缺少token");
        }

        Integer pageIndex = dto.getInteger("pageIndex") == null ? 1
                : dto.getInteger("pageIndex");
        Integer pageSize = dto.getInteger("pageSize") == null ? 10
                : dto.getInteger("pageSize");
        Pager pager = new Pager(pageIndex, pageSize);
        User user = servUser.getUserByName(dto.getString("userName"));
        if (ApiUtils.objIsEmpty(user)) {
            throw new ApiException("102", "用户不存在");
        }
        List<Map<String, Object>> list = accountNoticeService.getWithdrawlList(
                pager, user.getId());
        JSONObject data = new JSONObject();
        data.put("bills_list", list);
        data.put("count", pager.getRowCount());
        data.put("total_page", pager.getPageCount());
        data.put("current_page", pageIndex);
        msg = new ApiMessage("200", "查询成功");
        msg.setData(Des3.encResponse(data));
        return msg;
    }
}
